package cn.zhangxin.pethome.system.user.service.impl;

import cn.zhangxin.pethome.constants.BaseConstants;
import cn.zhangxin.pethome.system.logininfo.domain.Logininfo;
import cn.zhangxin.pethome.system.logininfo.mapper.LogininfoMapper;
import cn.zhangxin.pethome.system.user.domain.User;
import cn.zhangxin.pethome.system.user.mapper.UserMapper;
import cn.zhangxin.pethome.system.user.service.IUserService;
import cn.zhangxin.pethome.base.service.impl.BaseServiceImpl;
import cn.zhangxin.pethome.utils.BusinessException;
import cn.zhangxin.pethome.utils.MD5Utils;
import cn.zhangxin.pethome.utils.MobileUtil;
import cn.zhangxin.pethome.utils.StrUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author zx
 * @since 2023-01-11
 */
@Service
@Transactional(readOnly = true,propagation = Propagation.SUPPORTS)
public class UserServiceImpl extends BaseServiceImpl<User> implements IUserService {

    @Autowired
    private UserMapper userMapper;
    @Autowired
    private RedisTemplate redisTemplate;//注入redis
    @Autowired
    private LogininfoMapper logininfoMapper;
    //手机号用户注册
    @Override
    public void addPhone(User user) {
        //校验手机号是否为空
        if (user.getPhone() == null){
            throw new BusinessException("手机号为空");
        }
        //校验手机号合法性
        if (!MobileUtil.checkPhone(user.getPhone())){
            throw new BusinessException("手机号错误");
        }
        //校验该账号是否已经被注册
        User phone1 = userMapper.findPhone(user.getPhone());
        if (phone1!=null){
            throw new BusinessException("该账号已经注册请登录");
        }
        //校验短信是否为空
        if (user.getPhoneCode()==null || "".equals(user.getPhoneCode().trim())){
            throw new BusinessException("短信验证码为空");
        }
        //校验手机号验证码
        String VCodeRedisKey= user.getPhone() + BaseConstants.Redis.REGISTER;
        String VCodeRedis = (String)redisTemplate.opsForValue().get(VCodeRedisKey);
        if (VCodeRedis==null){
            throw new BusinessException("验证码已过期");
        }
        //校验短信验证码是否正确
        if (!VCodeRedis.equals(user.getPhoneCode())){
            throw new BusinessException("短信验证码错误");
        }
        //校验密码
        if (user.getPassword()==null || "".equals(user.getPassword().trim())){
            throw new BusinessException("密码不能为空");
        }
        //校验确认密码
        if (user.getPasswordRepeat()==null || "".equals(user.getPasswordRepeat().trim())){
            throw new BusinessException("确认密码不能为空");
        }
        //校验两次密码的重复性
        if (!user.getPasswordRepeat().equals(user.getPassword())){
            throw new BusinessException("两次密码不一致");
        }
        addpublic(user);

    }



    //邮箱注册
    @Override
    public void addEmail(User user) {

    }

    //绑定授权
    @Override
    public Long addBind(User user) {
        addpublic(user);
        return user.getId();
    }

    @Override
    public User findPhone(String phone) {
        return userMapper.findPhone(phone);
    }

    //公共的代码
    private void addpublic(User user) {
        //补全数据
        //用户名
        user.setUsername(user.getPhone());
        //状态
        user.setState(BaseConstants.User.STATE_REGISTER);
        //注册时间
        user.setCreatetime(new Date());
        //对密码进行加密
        String salt = StrUtils.getComplexRandomString(32);//随机生成一个32位的盐值
        user.setSalt(salt);
        //2 通过这个盐值加密
        String md5Pwd = MD5Utils.encrypByMd5(user.getPassword()+salt);
        user.setPassword(md5Pwd);

        //添加关联表的数据
        Logininfo logininfo = new Logininfo();
        //设置用户名
        logininfo.setUsername(user.getPhone());
        //设置电话号码
        logininfo.setPhone(user.getPhone());
        //设置盐值
        logininfo.setSalt(salt);
        //设置密码
        logininfo.setPassword(md5Pwd);
        //设置为用户
        logininfo.setType(BaseConstants.LogininfoType.STATE_USER);
        //设置为可用
        logininfo.setDisable(BaseConstants.LogininfoDisable.STATE_USABLE);
        //logininfo表添加数据
        logininfoMapper.add(logininfo);
        //获得logininfo在主键，并设置到user对象中
        user.setLogininfoId(logininfo.getId());
        //添加
        userMapper.add(user);
    }
}
